#include "process.h"

Process::Process(QObject *parent)
    : QObject(parent), QRunnable(), cond(new QWaitCondition), mutex(new QMutex)
{
}

void Process::run()
{
    mutex->lock();
    QSet<QString> uniqueNames; // 用于去重
    QList<QPair<QString, DWORD>> processList;
    WTS_PROCESS_INFOW *processInfo = nullptr;
    DWORD processCount = 0;

    if (EnumerateProcesses(processInfo, processCount))
    {
        std::unique_ptr<WTS_PROCESS_INFOW, void (*)(WTS_PROCESS_INFOW *)> processGuard(
            processInfo, [](WTS_PROCESS_INFOW *ptr)
            { if (ptr) WTSFreeMemory(ptr); });

        for (DWORD i = 0; i < processCount; ++i)
        {
            if (processInfo[i].pProcessName == nullptr)
            {
                continue; // 跳过空名称
            }
            QString processName = QString::fromWCharArray(processInfo[i].pProcessName);
            // 获取进程路径并检查是否属于系统服务
            if (processName.isEmpty() || uniqueNames.contains(processName) || isSystemService(processInfo[i].ProcessId))
            {
                continue; // 跳过空名称、重复名称或系统服务
            }
            uniqueNames.insert(processName); // 添加到集合
            processList.append(qMakePair(processName, processInfo[i].ProcessId));
        }
    }
    emit SendProcesses(processList);
    cond->wait(mutex);
    mutex->unlock();
}

bool Process::EnumerateProcesses(WTS_PROCESS_INFOW *&processInfo, DWORD &processCount)
{
    // 使用 WTSEnumerateProcessesW 获取进程信息
    if (WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &processInfo, &processCount))
    {
        emit SendDra("成功调用 WTSEnumerateProcessesW 获取进程信息");
        return true;
    }
    else
    {
        emit SendDra("无法调用 WTSEnumerateProcessesW 获取进程信息");
        return false;
    }
    return false;
}
bool Process::isSystemService(DWORD pid)
{
    wchar_t path[MAX_PATH] = {0};
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);

    if (hProcess)
    {
        if (GetModuleFileNameExW(hProcess, NULL, path, MAX_PATH))
        {
            QString processPath = QString::fromWCharArray(path).toLower();
            CloseHandle(hProcess);

            // 判断路径是否包含 System32
            if (processPath.contains("system32"))
            {
                emit SendDra(QString("进程 %1 是系统服务").arg(pid));
                return true;
            }
        }
        CloseHandle(hProcess);
    }

    return false;
}
